﻿Imports System.ComponentModel
Imports System.Text

''' <summary>
''' 組織単位（OU）を表すクラスです。
''' </summary>
''' <remarks></remarks>
<DataObject()>
Public NotInheritable Class OrganizationalUnit
  Inherits DomainObject

#Region " プライベートフィールド "
  Private _storedObjects As List(Of DomainObject)
#End Region

#Region " フレンドコンストラクター "
  ''' <summary>
  ''' <see cref="DirectoryEntry"/> を指定して <see cref="OrganizationalUnit"/> クラスの新しいインスタンスを初期化します。
  ''' </summary>
  ''' <param name="entry"><see cref="DirectoryEntry"/>。</param>
  ''' <remarks></remarks>
  Friend Sub New(entry As DirectoryEntry)
    MyBase.New(entry)
  End Sub
#End Region

#Region " パブリックプロパティ "
  ''' <summary>
  ''' 市区町村を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>市区町村。</returns>
  ''' <remarks></remarks>
  Public Property City As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("l").Value, String)
    End Get
    Set(ByVal value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("l").Value = value
    End Set
  End Property

  ''' <summary>
  ''' 郵便番号を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>郵便番号。</returns>
  ''' <remarks></remarks>
  Public Property PostalCode As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("postalCode").Value, String)
    End Get
    Set(ByVal value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("postalCode").Value = value
    End Set
  End Property

  ''' <summary>
  ''' 都道府県を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>都道府県。</returns>
  ''' <remarks></remarks>
  Public Property Prefecture As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("st").Value, String)
    End Get
    Set(ByVal value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("st").Value = value
    End Set
  End Property

  ''' <summary>
  ''' 直下のオブジェクトを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>直下のオブジェクトのコレクション。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property StoredDomainObjects As IList(Of DomainObject)
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      If _storedObjects Is Nothing Then
        _storedObjects = DirectoryAccess.GetStoredDomainObjects(Me)   '直下のオブジェクトを取得
      End If
      Return _storedObjects
    End Get
  End Property

  ''' <summary>
  ''' 番地を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>番地。</returns>
  ''' <remarks></remarks>
  Public Property Street As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("street").Value, String)
    End Get
    Set(ByVal value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("street").Value = value
    End Set
  End Property
#End Region

#Region " パブリックメソッド "
  ''' <summary>
  ''' 指定したパスの組織単位（OU）を検索します。このメソッドはデータバインド用です。
  ''' </summary>
  ''' <param name="path">パス。</param>
  ''' <returns>組織単位（OU）。</returns>
  ''' <remarks></remarks>
  <DataObjectMethod(DataObjectMethodType.Select)>
  Public Shared Function FindByPath(path As String) As OrganizationalUnit
    'distinguishedNameを生成
    Dim ouNames = path.Split("/"c).Reverse()
    Dim sb As New StringBuilder()
    For Each ouName In ouNames
      sb.AppendFormat("OU={0},", ouName)
    Next
    For Each dc In DirectoryAccess.DomainName.Split("."c)
      sb.AppendFormat("DC={0},", dc)
    Next
    sb.Length -= 1
    Return DirectCast(DirectoryAccess.FindDirectoryObject(sb.ToString(), CategoryType.OrganizationalUnit), OrganizationalUnit)
  End Function
#End Region

#Region " プロテクトメソッド "
  ''' <summary>
  ''' 使用されているリソースを解放し、オプションでマネージ リソースも解放します。
  ''' </summary>
  ''' <param name="disposing">マネージ リソースとアンマネージ リソースの両方を解放する場合は true。
  ''' アンマネージ リソースだけを解放する場合は false。</param>
  ''' <remarks></remarks>
  Protected Overrides Sub Dispose(disposing As Boolean)
    If _storedObjects IsNot Nothing Then
      DirectoryAccess.DisposeItems(_storedObjects)  'リソースを解放
      _storedObjects = Nothing
    End If
    MyBase.Dispose(disposing)
  End Sub
#End Region
End Class
